home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
asmutil
/
bluebook.zip
/
FILES.ASM
< prev
next >
Wrap
Assembly Source File
|
1986-05-11
|
12KB
|
386 lines
COMMENT ~
FILES.ASM -- File manipulation Procedures
From `BLUEBOOK of ASSEMBLY ROUTINES for the IBM PC & XT'
by Christopher L. Morgan
Copyright (C) 1984 by The Waite Group, Inc.
Contents:
---------
CBUF_CLR -- Clear the circular buffer
CBUF_IN -- Input to circular buffer
CBUF_INIT -- Initialize a circular buffer
CBUF_OUT -- Output to a circular buffer
CBUF_PUT -- Put a byte into a circular buffer
CLOS_FIL -- Close a file
EMSG_OUT -- Exception message output
FILT_CR* -- Filter for carriage return/linefeed
MAKE_FIL -- Create a file
READ_FIL -- Read bytes from a file
SAVE -- Save a file from communications line to disk
WRIT_FIL -- Write bytes to a file
>>>>> See FILES.DOC for complete descriptions of these routines. <<<<<
------------------------------------------------------------------------------
It is better to put this data in the source code calling these routines, and
then comment out this section. ~
DATAS SEGMENT PUBLIC
CR EQU 0DH ;ASCII code for carriage return
LF EQU 0AH ;ASCII code for linefeed
CTRL_Z EQU 1AH ;ASCII code for ^Z
BLK_SIZ = 0 ;K=block size
CBUF_SIZ DW 256 ;K=CBUF max capacity
CBUF DB 1 ;K=base address of CBUF
LBUF DB 256 DUP('LBUF')
NAME_BUF DB 64 DUP('NAME')
;
;Following table used by EMSG_OUT
EMSG DW EMSG1
DW EMSG2
DW EMSG3
DW EMSG4
DW EMSG5
DW EMSG6
DW EMSG7
DW EMSG8
DW EMSG9
DW EMSG10
DW EMSG11
DW EMSG12
DW EMSG13
DW EMSG14
DW EMSG15
DW EMSG16
DW EMSG17
DW EMSG18
EMSG1 DB CR,LF,'Invalid function number',CR,LF,0
EMSG2 DB CR,LF,'File not found',CR,LF,0
EMSG3 DB CR,LF,'Path not found',CR,LF,0
EMSG4 DB CR,LF,'Too many open files',CR,LF,0
EMSG5 DB CR,LF,'Access denied',CR,LF,0
EMSG6 DB CR,LF,'Invalid handle',CR,LF,0
EMSG7 DB CR,LF,'Memory control blocks destroyed',CR,LF,0
EMSG8 DB CR,LF,'Insufficient memory',CR,LF,0
EMSG9 DB CR,LF,'Invalid memory block address',CR,LF,0
EMSG10 DB CR,LF,'Invalid environment',CR,LF,0
EMSG11 DB CR,LF,'Invalid format',CR,LF,0
EMSG12 DB CR,LF,'Invalid access code',CR,LF,0
EMSG13 DB CR,LF,'Invalid data',CR,LF,0
EMSG14 DB CR,LF,'Message not in use',CR,LF,0
EMSG15 DB CR,LF,'Invalid drive was specified',CR,LF,0
EMSG16 DB CR,LF,'Attempted to remove the current directory',CR,LF,0
EMSG17 DB CR,LF,'Not same device',CR,LF,0
EMSG18 DB CR,LF,'No more files',CR,LF,0
DATAS ENDS
;------------------------------------------------------------------------------
;It is better to include this data in the source code calling these routines,
; and then comment out this section.
STACKS SEGMENT STACK
DB 20 DUP(' STACKS ')
STACKS ENDS
;------------------------------------------------------------------------------
CODES SEGMENT
;The following variables/constants must be defined in the source code calling
; these routines. See FILES.DOC.
EXTRN COM_INCK:FAR,COM_INIT:FAR,COM_ON:FAR,COM_OFF:FAR,MSG_OUT:FAR
EXTRN DTA:DWORD,LAST:BYTE,GAUGE:WORD,NEARFULL:WORD,NEAREMPTY:BYTE
PUBLIC EMSG_OUT,GET_SPEC,MAKE_FIL,CLOS_FIL,WRIT_FIL,READ_FIL
PUBLIC CBUF_INIT,CBUF_PUT,CBUF_IN,CBUF_CLR,CBUF_OUT,SAVE
ASSUME CS:CODES,DS:DATAS
;----------------------------I/O ROUTINES--------------------------------------
;Routine to send out exception messages
EMSG_OUT PROC FAR
PUSH SI ;Save registers
PUSH AX
ADD AX,AX ;Double to index through table
MOV SI,AX ;SI points into table
MOV SI,EMSG[SI] ;Look up address of message
CALL MSG_OUT ;Send the message
POP AX ;Restore registers
POP SI
RET
EMSG_OUT ENDP
;------------------------------------------------------------------------------
;Routine to get a file specifier
;
GET_SPEC PROC FAR
PUSH DS ;Save registers
PUSH ES
PUSH SI
PUSH DI
PUSH CX
;
;Set up pointer to DTA to get parameters
LDS SI,DTA ;Point to DTA for parameters
MOV CL,[SI] ;Get length of string
MOV CH,0 ;Make 16-bit
INC SI ;Skip the length byte
MOV AL,' ' ;Scan past the spaces
GET_SPEC1:
CMP [SI],AL ;Check for space
JNE GET_SPEC2 ;Exit loop if nonspace
INC SI ;Else point to next byte
LOOP GET_SPEC1 ;Loop back for more
JCXZ GET_SPEC3 ;No file specifier?
;
;Move the rest into place
GET_SPEC2:
MOV DI,DX ;Index points to destination
CLD ;Forward direction
REP MOVSB ;Make the transfer
CLC ;No error, so no carry
JMP GET_SPEC_XIT ; and return
GET_SPEC3:
MOV AX,20 ;No file specified
STC ;Set carry for error
JMP GET_SPEC_XIT ; and exit
GET_SPEC_XIT:
POP CX ;Restore registers
POP DI
POP SI
POP ES
POP DS
RET
GET_SPEC ENDP
;------------------------------------------------------------------------------
;Routine to create a file
;
MAKE_FIL PROC FAR
PUSH CX ;Save register
MOV CX,0 ;Attribute 0
INT 21H ;DOS call
POP CX ;Restore register
RET
MAKE_FIL ENDP
;------------------------------------------------------------------------------
;Routine to close a file
;
CLOS_FIL PROC FAR
MOV AH,3EH ;Close a file
INT 21H ;DOS call
RET
CLOS_FIL ENDP
;------------------------------------------------------------------------------
;Routine to write bytes to a file
;
WRIT_FIL PROC FAR
MOV AH,40H ;Write to a file
INT 21H ;DOS call
CMP AX,CX ;Was it all written?
JE WRIT_FIL_XIT ;Skip if yes
MOV AX,21 ;Not all bytes were transferred
STC ;Set carry for error
WRIT_FIL_XIT:
RET
WRIT_FIL ENDP
;------------------------------------------------------------------------------
;Routine to read bytes from a file
;
READ_FIL PROC FAR
MOV AH,3FH ;Read from a file
INT 21H ;DOS call
CMP AX,CX ;Everything back?
JE READFIL_XIT ;Skip if yes
MOV AX,22 ;Not all read
STC ;Set carry for error
READFIL_XIT:
RET
READ_FIL ENDP
;------------------------------------------------------------------------------
;Routine to handle input for a circular buffer
;
CBUF_INIT PROC FAR
MOV SI,0 ;Initialize SI
MOV DI,0 ;Initialize DI
MOV GAUGE,0 ; and # of bytes in buffer
MOV LAST,0 ; and last byte buffer
RET
CBUF_INIT ENDP
;------------------------------------------------------------------------------
;Routine to one byte into a circular buffer
;
CBUF_PUT PROC FAR
PUSH DX ;Save register
MOV DX,GAUGE ;Put V Guage in DX
MOV CBUF[DI],AL ;Put the byte into the buffer
INC DI ;Adjust pointer to next char
CMP DI,CBUF_SIZ ;Wrap it around?
JNE CBUF_PUT1 ;Skip if no wrap
MOV DI,0 ;Wraps back to zero
CBUF_PUT1:
INC DX ;Count the character
CMP DX,NEARFULL ;Too many characters?
JNE CBUF_PUT_XIT ;Skip if not
CALL COM_OFF ;Request to stop flow
CBUF_PUT_XIT:
POP DX ;Restore register
RET
CBUF_PUT ENDP
;------------------------------------------------------------------------------
;Routine to handle input to a circular buffer
;
CBUF_IN PROC FAR
CALL COM_INCK ;Check for a character
JZ CBUF_IN_XIT ;Good exit if none
AND AL,7FH ;Strip off parity bit
CMP AL,10 ;Check for <LF> (ASCII 10)
JNE CBUF_IN1 ;Skip if not <LF>
CMP LAST,13 ;Check for <CR> (ASCI 13)
JE CBUF_IN2 ;Skip if CR/LF
CBUF_IN1:
CALL CBUF_PUT ;Put byte into buffer
MOV LAST,AL ;Update last byte
CBUF_IN2:
CMP AL,13 ;Check for <CR>
JNE CBUF_IN3 ;Skip if not
;
;Insert LF if character was <CR>
PUSH AX ;Save the current character
MOV AL,10 ;<LF>
CALL CBUF_PUT ; goes into buffer
POP AX ;Restore current character
;
;Check for end of file
CBUF_IN3:
CMP AL,CTRL_Z ;Check for ^-Z (1AH)
JE CBUF_IN5 ;EOF is an exception
;
;Check for overflow
PUSH DX ;Save register
MOV DX,GAUGE
CMP DX,NEARFULL ;Overflow of characters?
JL CBUF_IN4 ;Skip if not
CALL COM_OFF ;Stop flow request
JMP CBUF_IN_XIT ;Good exit
CBUF_IN4: ;No overflow
CALL COM_ON ;Make sure flow is on
JMP CBUF_IN_XIT ;Good exit
CBUF_IN5: ;EOF exception handling
MOV AX,19 ;EOF exception code
STC ;Set carry